#include "../include/index.h"
#include<iostream>
#include <vector>
using namespace std;

unsigned int BKDRHash(const char *str)
{
    unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
    unsigned int hash = 0;

    while (*str)
    {
        hash = hash * seed + (*str++);
    }

    return (hash % 2000);
}

unsigned int numHash(int a)
{
    return (a% 2000);
}

    vector<int> * Chash_string::search(string Key)
    {
        vector<int> * result = new vector<int>;
        for(unsigned int i = 0; i < key[BKDRHash(Key.c_str())].size(); i ++)
        {
            if(key[BKDRHash(Key.c_str())][i] == Key)
            {
                result->push_back(id[BKDRHash(Key.c_str())][i]);
            }
        }
        return result;
    }

    vector<int> * Chash_int::search(int Key)
    {
        vector<int> * result = new vector<int>;
        for(unsigned int i = 0; i < key[Key%2000].size(); i ++)
        {
            if(key[Key%2000][i] == Key)
            {
                result->push_back(id[Key%2000][i]);
            }
        }
        return result;
    }
    //插入操作；
    void Chash_string::insert(string Key, int idcount)
    {
            key[BKDRHash(Key.c_str())].push_back(Key);
            id[BKDRHash(Key.c_str())].push_back(idcount);
    }
    void Chash_int::insert(int Key, int idcount)
    {
            key[numHash(Key)].push_back(Key);
            id[numHash(Key)].push_back(idcount);
    }
    void Chash_string::saveToFile(FILE * fout)
    {
        fprintf(fout,"%d\n",this->typeId);
        for(int i = 0 ; i < 2000 ; i ++)
        {
            fprintf(fout, "%d ", int(key[i].size()));
            for(unsigned int j = 0; j < key[i].size() ; j ++)
            {
                    fprintf(fout,"\'%s\' ",key[i][j].c_str());
                fprintf(fout,"%d ",id[i][j]);
            }
        }
    }
    void Chash_int::saveToFile(FILE * fout)
    {
        fprintf(fout,"%d\n",this->typeId);
        for(int i = 0 ; i < 2000 ; i ++)
        {
            fprintf(fout, "%d ", int(key[i].size()));
            for(unsigned int j = 0; j < key[i].size() ; j ++)
            {
                    fprintf(fout,"%d ",key[i][j]);
                fprintf(fout,"%d ",id[i][j]);
            }
        }
    }
    void Chash_string::recoverFromFile(FILE * fin)
    {
        this->typeId = 0;
        for(int i = 0 ; i < 2000 ; i ++)
        {
            int keysize;
            fscanf(fin, "%d ", &keysize);
            for(int j = 0; j < keysize ; j ++)
            {
                    char temp[150];int temp2;
                    fscanf(fin,"\'%[^\']*\' ",temp);
                    key[i].push_back(temp);
                    fscanf(fin,"%d ",&temp2);
                    id[i].push_back(temp2);
            }
        }
    }
    void Chash_int::recoverFromFile(FILE * fin)
    {
        this->typeId = 1;
        for(int i = 0 ; i < 2000 ; i ++)
        {
            int keysize;
            fscanf(fin, "%d ", &keysize);
            for(int j = 0; j < keysize ; j ++)
            {
                    int temp;
                    fscanf(fin,"%d ",&temp);
                    key[i].push_back(temp);
                    fscanf(fin,"%d ",&temp);
                    id[i].push_back(temp);
            }
        }
    }

Chash_string * Hash_string_CreateIndex(Table * source, int AttributeID)
{
    Chash_string * a = new Chash_string();
        vector<void*>* data = source->GetTableData();
        vector<void*>::iterator it;
        int idcount = 0;
        a->typeId = 0;
    for(it = data[AttributeID].begin();it != data[AttributeID].end();it++,idcount++)
    {
            a->insert(*(string*)*it,idcount);
    }
    return a;
}
Chash_int * Hash_int_CreateIndex(Table * source, int AttributeID)
{
    Chash_int * a = new Chash_int();
        vector<void*>* data = source->GetTableData();
        vector<void*>::iterator it;
        int idcount = 0;
        a->typeId = 1;
        //cout<< data[AttributeID].size()<<endl;
    for(it = data[AttributeID].begin();it != data[AttributeID].end();it++,idcount++)
    {
            a->insert(*(int*)*it,idcount);
            //cout<<idcount<<endl;
    }
    return a;
}
//建立名字为TableName_AttributeID.index的文件保存索引建立结果
vector<int> Hash_string_Search(Chash_string & hashtable, string * value)
{
    return * hashtable.search(*value);
}
vector<int> Hash_int_Search(Chash_int & hashtable, int * value)
{
    return * hashtable.search(*value);
}
